<?php
/**
 * Created by PhpStorm.
 * User: jocky
 * Date: 29/08/2017
 * Time: 17:36
 */
namespace common\models;

use common\models\ar\HistorySms;
use common\models\ar\UserTrade;

class Sms
{
    //短信提供商信息
   // private static $sms_provider = [
   //     'api' => 'http://120.55.197.77:1210/Services/MsgSend.asmx/SendMsg?',
   //     'account' => 'cpkj',
   //     'password' => 'cpkj0620',
   // ];
    //public $password=(string)strtoupper(md5('cpkj0620'));
    private static $sms_provider = [
        'api' => 'http://www.yescloudtree.cn:28009',
        'UserName' => 'cpkj',
        'password' =>'cpkj0620',
        'Action'=>'sendsms',
    ];

    //短信类型、有效期
    //限制条件：M分钟内最多发送N条短信
    private static $sms_type = [
        1 => [ //注册
            'desc' => 'register',
            'in' => 1,
            'times' => 1,
            'duration' => 1,
        ],

        2 => [//登录，保留
            'desc' => 'login',
            'in' => 1,
            'times' => 10,
            'duration' => 3,
        ],

        3 => [//修改密码，保留
            'desc' => 'update_password',
            'in' => 10,
            'times' => 5,
            'duration' => 3,
        ],

        4 => [//找回密码
            'desc' => 'forget_password',
            'in' => 10,
            'times' => 5,
            'duration' => 3,
        ],

        5 => [//绑定新的手机号码
            'desc' => 'bind_cellphone',
            'in' => 10,
            'times' => 5,
            'duration' => 3,
        ],

       6 => [//注册成功发送用户名和密码
           'desc' => 'rebind_cellphone',
           'in' => 10,
           'times' => 5,
           'duration' => 3,
       ],

        7 => [//找回安全码
            'desc' => 'update_safe_code',
            'in' => 10,
            'times' => 5,
            'duration' => 3,
        ],

        8 => [//一般通知
            'desc' => 'notice',
            'in' => 30,
            'times' => 1,
            'duration' => 0,//此类型短信没有验证码
        ],
    ];


    /**
     * 发送短信
     *
     * @param string $cellphone 手机号码
     * @param int $type 发送短信的类型
     * @param string $msg_pass 如果为一般通知类，传入通知类短信内容
     *
     * @return mixed
     *
     */
    public static function send($cellphone, $type,$name='',$password='', $msg_pass = '')
    {
        //手机号码、类型、次数的检测
        $check = self::check($cellphone, $type);
        if ($check['code'] != 1) {
            exit(json_encode($check));
        }
        //在数据库里生成一条记录
        $code = (string)mt_rand(100000, 999999);
        $msg = "";
        if ($type == 6) {
            $msg .= "您的注册用户名：".$name."密码:".$password."妥善保管，请勿泄露给他人。";
        }
        if ($type != 8 && $type != 6) {
            $msg .= "您好！您的手机短信验证码为：" . $code;
            $msg .= "（" . self::$sms_type[$type]['duration'] . "分钟之内有效）";
            $msg .= "，请在页面输入完成验证，如非本人操作请忽略。";
        } else {
            $msg .= $msg_pass;
        }

        // $msg .= "【期权通】";

        //写到数据库中
        $smsObj = new HistorySms();
        $smsObj->cellphone = $cellphone;
        $smsObj->send_time = time();
        $smsObj->code = $code;
        $smsObj->duration = self::$sms_type[$type]['duration'];
        $smsObj->type = $type;
        $smsObj->valid = 0;//无效状态，等发送成功后，将其置为1，表示有效状态
        $smsObj->content = $msg;
        $smsObj->data_response = '';
        $smsObj->save();

        $bool = false;
        if (YII_ENV == 'dev') {
            $return = self::sendToProvider($cellphone, $msg);
            $smsObj->data_response = $return['result'];
            $smsObj->save();
            //var_dump($return);
            //exit();
            $bool = $return['status'];
        }
        //发送成功后，将该条短信置为有效状态
        if (YII_DEBUG || $bool) {
            $code = 1;
            $msg = "发送成功";
            $smsObj->valid = 1;
            $smsObj->save();
        } else {
            $code = 0;
            $msg = "发送失败";
        }

        return ['code' => $code, 'msg' => $msg];
    }

    /**
     * 通过第三方短信提供商将短信发给用户
     *
     * @param string $cellphone 需要发送短信的手机号码
     * @param string $msg 短信内容
     *
     * @return array
     */
    private static function sendToProvider($cellphone, $msg)
    {
        $return = ['status' => true, 'result' => ''];
        $params = [
            'UserName' => self::$sms_provider['UserName'],
            'password' => self::$sms_provider['password'],
            'Mobile' => $cellphone,
            'Message' => $msg,
            'Action' => self::$sms_provider['Action'],
        ];
        $params['password']=strtoupper(md5($params['password']));
        $params['Message']=base64_encode($params['Message']);
        $result = self::http_post_data(self::$sms_provider['api'],json_encode($params));
        // return $result;
        // $options = [
        //     CURLOPT_URL => self::$sms_provider['api'] . json_encode($params),
        //     CURLOPT_HEADER => false,
        //     CURLOPT_CONNECTTIMEOUT => 3,
        //     CURLOPT_RETURNTRANSFER => 1,
        // ];
        // curl_setopt_array($ch, $options);
        // $result = curl_exec($ch);
        // $result = (array)simplexml_load_string($result);
        // if (curl_errno($ch)) {
        //     $return['status'] = false;
        //     $return['result'] = curl_error($ch);
        // } else {
        //     $return['result'] = $result[0];

        //     $tmp = substr($result[0], 0, 1);
        //     if ($tmp == '-') {//错误
        //         $return['status'] = false;
        //     } else {//成功
        //         $return['status'] = true;
        //     }
        // }
        // curl_close($ch);
        $json=json_decode($result,true);
        if ($json['Status']==0) {
            $return['status'] = true;
            $return['result'] = '1';
        } else {
            $return['status'] = false;
            $return['result'] = '0';
        }
        return $return;
    }

    /**
     * 短信类型、手机号码、发送次数的检测
     *
     * @param $cellphone
     * @param $type
     *
     * @return array
     */
    public static function check($cellphone, $type)
    {
        //1：类型检测
        if (!isset(self::$sms_type[$type])) {
            return ['code' => 5001, 'msg' => '类型不存在'];
        }

        //2：手机号检测
        $check = Common::dataCheck($cellphone, [
            'type' => 3,
            'min' => 11,
            'max' => 11,
            'detail' => [
                'pattern' => '/^1[34578][0-9]{9}$/',
                'info' => '手机号码不正确'
            ],
        ]);

        if ($check['code'] != 1) {
            return ['code' => 5002, 'msg' => $check['msg']];
        }

        //3：非注册、非绑定、非通知类短信，需要检测该手机号是否有相应的绑定账号
        if (!in_array($type, [1, 5, 8])) {
            $lists = UserTrade::find()->where(['cellphone' => $cellphone])->one();
            if (!$lists) {
                return ['code' => 5003, 'msg' => '绑定账户不存在'];
            }
        }

        //4：发送次数检测
        $end = time();
        $start = $end - 60 * self::$sms_type[$type]['in'];
        $sql = "
                SELECT
                    `cellphone`
                FROM
                    `history_sms`
                WHERE
                    `cellphone` = :cellphone 
                AND `send_time` >= :start 
                AND `send_time` <= :end 
                AND `valid` != 0 
                AND `type` = :type
        ";
        $count = HistorySms::findBySql($sql, [
            ':cellphone' => $cellphone,
            ':start' => $start,
            ':end' => $end,
            ':type' => $type
        ])->count();
        if ($count >= self::$sms_type[$type]['times']) {
            return ['code' => 5004, 'msg' => '短信次数已达上限'];
        }

        return ['code' => 1, 'msg' => 'ok'];
    }

    /**
     * 手机短信验证码检测
     *
     * @param $cellphone
     * @param $code
     * @param $type
     *
     * @return array
     */
    public static function smsCodeCheck($cellphone, $code, $type = 1)
    {
        $time = time();
        //短信验证码
        $sql = "
                SELECT
                  `code`,
                  `send_time`,
                  `duration`
                FROM
                  `history_sms`
                WHERE `cellphone` = :cellphone
                AND `send_time` >= " . $time . " - `duration` *60
                AND `type` = :type
                AND `valid` = 1
                ORDER BY `send_time` DESC
                LIMIT 1
        ";
        $obj = HistorySms::findBySql($sql, [':cellphone' => $cellphone, ':type' => $type])->one();
        if (!$obj) {
            return ['code' => 6001, 'msg' => '请获取短信验证码'];
        }

        if ($code != $obj->code) {
            return ['code' => 6001, 'msg' => '短信验证码不正确'];
        }
        return ['code' => 1, 'msg' => 'ok'];
    }
public function execResult($result){

        return $result;
    }

public static function http_post_data($url, $data_string) {  
    $ch = curl_init();  
    curl_setopt($ch, CURLOPT_POST, 1);  
    curl_setopt($ch, CURLOPT_URL, $url);  
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);  
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(  
        "Content-Type: application/json; charset=utf-8",  
        "Content-Length: " . strlen($data_string))  
    );  
    ob_start();  
    curl_exec($ch);  
    $return_content = ob_get_contents();  
    ob_end_clean();  
     
    return  $return_content;  
    }
}
